#ifndef _TIMER_QUEUE_H_
#define _TIMER_QUEUE_H_

#include <list>
#include "Non_Copyable.h"
#include "Timer_Node.h"
#include "Timer_Queue_Iterator.h"

const int MAX_TIMER_QUEUE = 10240;

template <class TYPE>
class Timer_Queue :public Non_Copyable
{
public:
	/// Type of Iterator.
	typedef Timer_Queue_Iterator<TYPE> ITERATOR;

	// Default constructor.
	Timer_Queue ( std::list<Timer_Node <TYPE> > *freelist = 0 );

	/// Destructor - make virtual for proper destruction of inherited classes.
	virtual ~Timer_Queue (void);

	/// True if queue is empty, else false.
	virtual int is_empty (void) const = 0;

	//Returns the time of the earlier node in the Timer_Queue.Must be called on a non-empty queue.
	virtual unsigned long earliest_time (void) const = 0;

	//schedule
	virtual long schedule (const TYPE &type,
		const void *arg,
		unsigned long future_time,
		unsigned long interval = 0);


	// Resets the interval of the timer 
	virtual int reset_interval (long timer_id,
		unsigned long interval) = 0;

	//Cancel all timer associated with <type>. 
	virtual int cancel (const TYPE &type,
		int dont_call_handle_close = 1) = 0;

	virtual int cancel (long timer_id,
		const void **arg = 0,
		int dont_call_handle_close = 1) = 0;

	//expire
	virtual int expire (unsigned long current_time);

	/* virtual */ int expire (void);


	/// Determine the next event to timeout.  Returns <max> if there are
	/// no pending timers or if all pending timers are longer than max.
	/// This method acquires a lock internally since it modifies internal state.
	virtual unsigned long calculate_timeout (unsigned long max);

	/**
	* Determine the next event to timeout.  Returns <max> if there are
	* no pending timers or if all pending timers are longer than max.
	* <the_timeout> should be a pointer to storage for the timeout value,
	* and this value is also returned.  This method does not acquire a
	* lock internally since it doesn't modify internal state.  If you
	* need to call this method when the queue is being modified
	* concurrently, however, you should make sure to acquire the <mutex()>
	* externally before making the call.
	*/
	virtual unsigned long calculate_timeout (unsigned long max,
		unsigned long the_timeout);

	/// Returns a pointer to this ACE_Timer_Queue's iterator.
	virtual ITERATOR &iter (void) = 0;

	//Removes the earliest node from the queue and returns it.
	virtual Timer_Node<TYPE> *remove_first (void) = 0;

	/// Reads the earliest node from the queue and returns it.
	virtual Timer_Node<TYPE> *get_first (void) = 0;

	/// Method used to return a timer node to the queue's ownership
	/// after it is returned by a method like <remove_first>.
	virtual void return_node (Timer_Node<TYPE> *);

protected:

	/// Schedule a timer.
	virtual long schedule_i (const TYPE &type,
		const void *arg,
		const unsigned long future_time,
		const unsigned long interval) = 0;

	//Reschedule an "interval" <Timer_Node>.
	virtual void reschedule (Timer_Node<TYPE> *) = 0;

	/// Factory method that allocates a new node.
	virtual Timer_Node<TYPE> *alloc_node (void);

	/// Factory method that frees a previously allocated node.
	virtual void free_node (Timer_Node<TYPE> *);

	/// Class that implements a free list
	std::list<Timer_Node<TYPE> > *free_list_;

	/// Flag to delete only if the class created the <free_list_>
	int delete_free_list_;

private:

	/// Returned by <calculate_timeout>.
	unsigned long timeout_;

};

#include "Timer_Queue.cpp"
#endif